package com.pengliu.config.security;

import java.util.Arrays;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import com.pengliu.common.bean.SysAuth;
import com.pengliu.service.impl.UserDetailServiceImpl;
import com.pengliu.util.Constants;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
	
	@Autowired
	private PasswordEncoder passwordEncoder;
	
	@Autowired
	private UserDetailServiceImpl userDetailService;
	
	@Autowired
    private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;
	
	@Autowired
	private SecuritySuccessHandler securitySuccessHandler;
	
	/**
	 * user: pengliu
	 * date: 2017年9月26日
	 * desc: 请求授权
	 * @param http
	 * @throws Exception
	 */
	protected void configure(HttpSecurity http) throws Exception {
		
		ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
		
		registry.antMatchers(HttpMethod.GET,"/login","/code","/oss/authOss","/ossGet/**").permitAll();		//允许不登陆访问地址
		registry.antMatchers(HttpMethod.POST,"/oss/").permitAll();								//允许不登陆访问地址
				
		
		List<SysAuth> listSysAuth = userDetailService.getSysAuthAll();
		for (SysAuth sysAuth : listSysAuth) {
			registry.antMatchers(sysAuth.getUrl()).hasAnyAuthority(sysAuth.getName());
		}
		
		//登陆成功后跳转的URL
		securitySuccessHandler.setDefaultTargetUrl("/index");
		registry.and().csrf().disable()
		        .formLogin()
		        .loginPage("/login")
		        .failureUrl("/login?error=1")
		        .usernameParameter("username")
		        .passwordParameter("password")
		        //添加扩展参数
		        .authenticationDetailsSource(authenticationDetailsSource)
		        //登陆成功后操作
		        .successHandler(securitySuccessHandler);
		
		registry.and()
			.rememberMe()
			.userDetailsService(userDetailService)
			.tokenValiditySeconds(2419200)
			.key(Constants.PWDKEY);
		
		registry.and()
			.logout()
			.deleteCookies("uid")
			.logoutSuccessUrl("/login");
		
		registry.and()
			.authorizeRequests()
			.anyRequest()
			.authenticated();
	}
	/**
	 * user: pengliu
	 * date: 2017年9月26日
	 * desc: 认证账号密码以及角色
	 * @param auth
	 * @throws Exception
	 */
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		SecurityProvider provider = new SecurityProvider();
        provider.setHideUserNotFoundExceptions(false);
        provider.setUserDetailsService(userDetailService);
        provider.setPasswordEncoder(passwordEncoder);
		auth.authenticationProvider(provider);
	}
	
	
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers(
			"/static/**",
			"/lib/**",
			"/test/**"
		);
	}
}
